﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    public class Level1
    {
        float time = 0;
        AlienManager alienManager;

        float ReverseX(float x, bool reverse)
        {
            if (reverse)
                return Game1.width - x;
            else
                return x;
        }

        public void WaveSmallGoto(int count, Vector2 start, Vector2 end, float delay)
        {
            for (int i = 0; i < count; i++)
            {
                AlienEvent ae = new AlienEvent();
                ae.time = time;
                ae.start = start;
                ae.end = end;
                ae.speed = 200;
                ae.colorIndex = i / 3;
                ae.OnTime += new AlienEvent.OnTimeDelegate(AlienSmallGoTo);
                alienManager.events.Add(ae);
                time += delay;
            }
        }

        public void WaveDiagonal(bool rx)
        {
            float backup = time;

            for (int y = 0; y < 6; y++)
            {
                time = backup;
                float yoffset = y * 64;
                WaveSmallGoto(8, new
                    Vector2(ReverseX(Game1.width + 32, rx), 64 + yoffset),
                    new Vector2(ReverseX(-32, rx), 364 + yoffset),
                    0.75f);
            }
        }


        public void Setup(AlienManager alienManager)
        {
            this.alienManager = alienManager;

            bool waves = false;
            bool boss = true;

            if (waves)
            {
                float backup = time;

                WaveGoingDownColumns(1);
                WaveGoingDownColumns(2);
                WaveGoingDownColumns(3);

                time -= 1;
                Wave2Diagonals();

                WaveGoingDownColumns(2);
                WaveGoingDownColumns(3);

                time -= 1;
                WaveFatColumns(1);
                time += 1;
                WaveFatColumns(2);
                time += 1;

                Wave2Diagonals();

                time -= 1;
                WaveFatColumns(3);
                time += 1;

                Wave2Diagonals();
                time += 1;

                WaveGoingDownColumns(2);
                WaveGoingDownColumns(3);
                WaveGoingDownColumns(4);

                WaveFatColumns(2);
                time += 1;
                WaveFatColumns(4);
                time += 1;

                Wave2Diagonals();

                WaveFatColumns(4);
                WaveGoingDownColumns(4);
                WaveGoingDownColumns(5);

            }

            if (boss)
            {
                AlienEvent ae = new AlienEvent();
                ae.time = time;
                ae.OnTime += new AlienEvent.OnTimeDelegate(Boss);
                alienManager.events.Add(ae);
            }
        }

        private void WaveFatColumns(float columns)
        {
            for (int x = 1; x <= columns; x++)
                WaveSingleFatGoDown((Game1.width / (columns + 1)) * x);
        }

        private float WaveGoingDownColumns(float columns)
        {
            float backup = time;
            for (int x = 1; x <= columns; x++)
            {
                time = backup;
                float px = (Game1.width / (columns + 1)) * x;
                WaveSmallGoto(6, new Vector2(px, -32), new Vector2(px, Game1.height + 32), 0.5f);
            }
            return backup;
        }

        private void Wave2Diagonals()
        {
            WaveDiagonal(true);
            time -= 2;
            WaveSingleFatGoDown(Game1.width - 200);

            WaveDiagonal(false);
            time -= 2;
            WaveSingleFatGoDown(200);
        }

        private void WaveSingleFatGoDown(float x)
        {
            {
                AlienEvent ae = new AlienEvent();
                ae.time = time;
                ae.start = new Vector2(x, -32);
                ae.OnTime += new AlienEvent.OnTimeDelegate(AlienFatPauseFireGoDown);
                alienManager.events.Add(ae);
            }
        }

        private void WaveSmallGoDown(int count, float x)
        {
            for (int i = 0; i < 5; i++)
            {
                AlienEvent ae = new AlienEvent();
                ae.time = time;
                ae.start = new Vector2(x, -32);
                ae.OnTime += new AlienEvent.OnTimeDelegate(AlienSmallGoTo);
                alienManager.events.Add(ae);
                time += 1.0f;
            }
        }

        void AlienFatPauseFireGoDown(AlienEvent ev)
        {
            AlienFat alien = new AlienFat();
            alien.pos = ev.start;
            alien.size = new Vector2(64, 64);
            alienManager.aliens.Add(alien);
        }


        void AlienSmallGoTo(AlienEvent ev)
        {
            Alien alien = new Alien();
            alien.pos = ev.start;
            alien.colorIndex = ev.colorIndex;

            StateShoot stateShoot = new StateShoot(alien);
            stateShoot.delayMin = 2;
            stateShoot.delayMax = 5;
            stateShoot.dirMin = new Vector2(-32, -32);
            stateShoot.dirMax = new Vector2(+32, +32);

            StateGoto stateGoto = new StateGoto(alien);
            stateGoto.dest = ev.end;
            stateGoto.speed = ev.speed;

            StateParallel stateParallel = new StateParallel(alien);
            stateParallel.states.Add(stateGoto);
            stateParallel.states.Add(stateShoot);

            alien.stateMachine.state = stateParallel;
            alien.lifePoint = 5;
            alienManager.aliens.Add(alien);
        }

        void Boss(AlienEvent ev)
        {
            Level1Boss.Setup(alienManager);
        }

    }
}
